//=============================================================================
/**
 * @file	gym_elec.c
 * @brief	カントー電気ジムギミック
 * @author	Nozomu Saito
 *
 * モジュール名：GYM_
 *
 */
//=============================================================================
#include "common.h"
#include "fieldsys.h"
#include "fieldmap_work.h"
#include "system/snd_tool.h"
#include "include/savedata/gimmickwork.h"
#include "../fielddata/build_model/build_model_id.h"

#include "field_gimmick_def.h"
#include "gym_def.h"

#include "gym_local.h"
#include "gym_init.h"

#include "gym.h"

#include "gym_elec_def.h"

#include "fielddata/eventdata/zone_t06gym0101evc.h"

#define	ANM_CMD_NUM	(2)
#define DUMMY_MOVE_OBJ	(3)

//SE
#define SE_ELEC_GIMMICK		(SEQ_SE_DP_UG_020)


enum{
	SEQ_SET_TARGET,
	SEQ_ROCK_UP_ANM,
	SEQ_ROCK_DOWN_ANM,
	SEQ_ANM_WAIT,
	SEQ_3D_ANM_OFF,
	SEQ_3D_ANM_ON,
	SEQ_END
};

typedef struct ELEC_GYM_TEMP_WORK_tag
{
	FIELDSYS_WORK *fsys;
}ELEC_GYM_TEMP_WORK;

typedef struct {
	FIELDSYS_WORK *fsys;
	FIELD_OBJ_PTR ObjPtr[3];
	int AnmTarget;
	u16 AcmdCounter;
	u8 AnmSeq;
	u8 dummy;

}EVENT_GYM_WORK;

static BOOL RockOBJMoveEvt(GMEVENT_CONTROL * event);

//---------------------------------------------------------------------------
/**
 * @brief	電気ジム:セットアップ
 *
 * @param	fsys	フィールドシステムポインタ
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void GYM_SetupElecGym(FIELDSYS_WORK *fsys)
{
	ELEC_GYM_TEMP_WORK *elec_temp;
	GIMMICKWORK *work;
	ELEC_GYM_WORK *elec_gym_work;

	//ここでギミックワークの中身を見る
	work = SaveData_GetGimmickWork(GameSystem_GetSaveData(fsys));
	elec_gym_work = (ELEC_GYM_WORK*)GIMMICKWORK_Get(work, FLD_GIMMICK_ELEC_GYM_K);

	//ジム専用ワークをアロケートして、フィールドマップ汎用ワークポインタにあてる
	fsys->fldmap->Work = sys_AllocMemory(HEAPID_FIELD, sizeof(ELEC_GYM_TEMP_WORK));
	//初期化
	MI_CpuClear8(fsys->fldmap->Work, sizeof(ELEC_GYM_TEMP_WORK));
	elec_temp = fsys->fldmap->Work;

	elec_temp->fsys = fsys;

	//2つのスイッチ状態をみて、アニメーションを切り替える
	{
		u8 anm_num;
		u8 i;
		F_OBJ_DATA	*obj;
		if (elec_gym_work->Switch1OK){
			obj = F_RES_OBJ_GetRenderObjPtr(fsys->FldResObjMng, BMID_ROOM_MG09_ES1);
			//指定ＯＢＪアニメ数を入手
			anm_num = F3DA_GetAnimeNum(fsys->field_3d_anime, BMID_ROOM_MG09_ES1);
			//3Dアニメパージ
			for(i=0;i<anm_num;i++){
				F3DA_RemoveFld3DAnime(	fsys->field_3d_anime,
										&obj->RenderObj,
										BMID_ROOM_MG09_ES1,
										i	);
			}
		}
		if (elec_gym_work->Switch2OK){
			obj = F_RES_OBJ_GetRenderObjPtr(fsys->FldResObjMng, BMID_ROOM_MG09_ES2);
			//指定ＯＢＪアニメ数を入手
			anm_num = F3DA_GetAnimeNum(fsys->field_3d_anime, BMID_ROOM_MG09_ES2);
			//3Dアニメパージ
			for(i=0;i<anm_num;i++){
				F3DA_RemoveFld3DAnime(	fsys->field_3d_anime,
										&obj->RenderObj,
										BMID_ROOM_MG09_ES2,
										i	);
			}
		}
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	電気ジム:終了処理
 *
 * @param	fsys	フィールドシステムポインタ
 *
 * @return	none
 */
//---------------------------------------------------------------------------
void GYM_EndElecGym(FIELDSYS_WORK *fsys)
{
	ELEC_GYM_TEMP_WORK *elec_temp;
	elec_temp = (ELEC_GYM_TEMP_WORK *)fsys->fldmap->Work;
	sys_FreeMemoryEz(elec_temp);
	fsys->fldmap->Work = NULL;
}

//---------------------------------------------------------------------------
/**
 * @brief	電気ジム:スイッチチェック
 *
 * @param	fsys	フィールドシステムポインタ
 * @apram	inDustBoxID		ゴミ箱のID
 *
 * @return	施錠状態
 */
//---------------------------------------------------------------------------
u8 GYM_CheckElecSwitch(FIELDSYS_WORK *fsys, const u8 inDustBoxID)
{
	GIMMICKWORK *work;
	ELEC_GYM_WORK *elec_gym_work;

	//ギミックワークの中身を見る
	work = SaveData_GetGimmickWork(GameSystem_GetSaveData(fsys));
	elec_gym_work = (ELEC_GYM_WORK*)GIMMICKWORK_Get(work, FLD_GIMMICK_ELEC_GYM_K);

	//両スイッチを押下済？
	if ( elec_gym_work->Switch1OK && elec_gym_work->Switch2OK ){
		//ロック開錠済
		return ELEC_GM_SW_ALL_OK;
	}else if ( elec_gym_work->Switch1OK ){	//一番スイッチ押しているか？
		//押したのは2番スイッチか？
		if ( inDustBoxID == elec_gym_work->SwitchPos2 ){
			//2番スイッチ押下成功
			return ELEC_GM_SW2_OK;
		}else{
			//ハズレ。さらに1番ロック復活
			return ELEC_GM_SW2_NG;
		}
	}else{
		//押してない
		if ( inDustBoxID == elec_gym_work->SwitchPos1 ){
			//1番スイッチ押下成功
			return ELEC_GM_SW1_OK;
		}else{
			//ハズレ
			return ELEC_GM_SW_NG;
		}
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	電気ジム:スイッチアニメON/OFF
 *
 * @param	fsys	フィールドシステムポインタ
 * @param	inRockID	ロック番号
 * @param	inState		セットする状態
 *
 * @return	施錠状態
 */
//---------------------------------------------------------------------------
void GYM_SetElecRock(FIELDSYS_WORK *fsys, const u8 inRockID, const u8 inState)
{
	EVENT_GYM_WORK * egw;
	GIMMICKWORK *work;
	ELEC_GYM_WORK *elec_gym_work;

	//ギミックワークの中身を見る
	work = SaveData_GetGimmickWork(GameSystem_GetSaveData(fsys));
	elec_gym_work = (ELEC_GYM_WORK*)GIMMICKWORK_Get(work, FLD_GIMMICK_ELEC_GYM_K);

	egw = sys_AllocMemoryLo(HEAPID_WORLD, sizeof(EVENT_GYM_WORK));

	switch(inRockID){
	case 0:
		egw->AnmTarget = BMID_ROOM_MG09_ES1;
		if (inState){
			//ロック
			egw->AnmSeq = SEQ_ROCK_DOWN_ANM;
			FieldEvent_Call(fsys->event, RockOBJMoveEvt, egw);
			//フラグ操作
			elec_gym_work->Switch1OK = 0;
		}else{
			//アンロック
			egw->AnmSeq = SEQ_ROCK_UP_ANM;
			FieldEvent_Call(fsys->event, RockOBJMoveEvt, egw);
			//フラグ操作
			elec_gym_work->Switch1OK = 1;
		}
		break;
	case 1:
		egw->AnmTarget = BMID_ROOM_MG09_ES2;
		if (inState){
			//ロック		2番ロックがかかることは無い
			GF_ASSERT(0);
			sys_FreeMemoryEz(egw);
		}else{
			//アンロック
			egw->AnmSeq = SEQ_ROCK_UP_ANM;
			FieldEvent_Call(fsys->event, RockOBJMoveEvt, egw);
			elec_gym_work->Switch2OK = 1;
		}
		break;
	default:
		GF_ASSERT(0);
	}
}

//---------------------------------------------------------------------------
/**
 * @brief	透明OBJの移動イベント
 *
 * @param	event	イベントポインタ
 *
 * @return	BOOL	TRUEでイベント終了
 */
//---------------------------------------------------------------------------
static BOOL RockOBJMoveEvt(GMEVENT_CONTROL * event)
{
	FIELDSYS_WORK * fsys = FieldEvent_GetFieldSysWork(event);
	EVENT_GYM_WORK * egw = FieldEvent_GetSpecialWork(event);
	int *seq = FieldEvent_GetSeqWork(event);

	switch(*seq){
	case SEQ_SET_TARGET:		//移動対象の決定
		if (egw->AnmTarget == BMID_ROOM_MG09_ES1){
			egw->ObjPtr[0] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY04);
			egw->ObjPtr[1] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY05);
			egw->ObjPtr[2] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY06);
		}else{	//BMID_ROOM_MG09_ES2
			egw->ObjPtr[0] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY01);
			egw->ObjPtr[1] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY02);
			egw->ObjPtr[2] = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, T06GYM0101_DUMMY03);
		}
		egw->AcmdCounter = 0;
		(*seq) = egw->AnmSeq;
		break;
	case SEQ_ROCK_UP_ANM:		//移動アニメ
		FieldOBJ_AcmdSet(egw->ObjPtr[0],AC_WALK_L_2F);
		FieldOBJ_AcmdSet(egw->ObjPtr[1],AC_WALK_L_2F);
		FieldOBJ_AcmdSet(egw->ObjPtr[2],AC_WALK_R_2F);
		(*seq) = SEQ_ANM_WAIT;
		break;
	case SEQ_ROCK_DOWN_ANM:
		FieldOBJ_AcmdSet(egw->ObjPtr[0],AC_WALK_R_2F);
		FieldOBJ_AcmdSet(egw->ObjPtr[1],AC_WALK_R_2F);
		FieldOBJ_AcmdSet(egw->ObjPtr[2],AC_WALK_L_2F);
		(*seq) = SEQ_ANM_WAIT;
		break;
	case SEQ_ANM_WAIT:		//アニメ待ちシーケンス
		{
			u8 i ;
			for (i=0;i<DUMMY_MOVE_OBJ;i++){
				if ( !FieldOBJ_AcmdSetCheck(egw->ObjPtr[i]) ){
					break;
				}
			}
			if (i==DUMMY_MOVE_OBJ){
				//アニメ数加算
				egw->AcmdCounter++;
				//アニメ終了
				if (egw->AcmdCounter >= ANM_CMD_NUM){	//アニメ規定数こなしたか？
					//次のシーケンスへ
					if ( egw->AnmSeq == SEQ_ROCK_UP_ANM ){
						(*seq) = SEQ_3D_ANM_OFF;
					}else{		//SEQ_ROCK_DOWN_ANM
						(*seq) = SEQ_3D_ANM_ON;
					}
				}else{
					//アニメシーケンスへ
					(*seq) = egw->AnmSeq;
				}
			}
		}
		break;
	case SEQ_3D_ANM_OFF:
		{
			u8 i;
			u8 anm_num;
			F_OBJ_DATA	*obj;
			OS_Printf("target = %d\n",egw->AnmTarget);
			obj = F_RES_OBJ_GetRenderObjPtr(fsys->FldResObjMng, egw->AnmTarget);
			//指定ＯＢＪアニメ数を入手
			anm_num = F3DA_GetAnimeNum(fsys->field_3d_anime, egw->AnmTarget);
			//3Dアニメパージ
			for(i=0;i<anm_num;i++){
				F3DA_RemoveFld3DAnime(	fsys->field_3d_anime,
										&obj->RenderObj,
										egw->AnmTarget,
										i	);
			}
			Snd_SePlay( SE_ELEC_GIMMICK );
		}
		(*seq) = SEQ_END;
		break;
	case SEQ_3D_ANM_ON:
		{
			u8 i;
			u8 anm_num;
			F_OBJ_DATA	*obj;
			obj = F_RES_OBJ_GetRenderObjPtr(fsys->FldResObjMng, egw->AnmTarget);
			//指定ＯＢＪアニメ数を入手
			anm_num = F3DA_GetAnimeNum(fsys->field_3d_anime, egw->AnmTarget);
			for(i=0;i<anm_num;i++){
				F3DA_SetFld3DAnime(	egw->AnmTarget,
									i,
									FALSE,
									&obj->RenderObj,
									fsys->field_3d_anime);
			}
			Snd_SePlay( SE_ELEC_GIMMICK );
		}
		(*seq) = SEQ_END;
		break;
	case SEQ_END:
		//終了
		sys_FreeMemoryEz(egw);
		return TRUE;
	}
	return FALSE;
}